<template>
  <el-popover
    placement="bottom"
    :width="250"
    trigger="click"
    ref="popoverRef"
    @show="handlePopoverShow"
    @hide="handlePopoverHide"
  >
    <template #reference>
      <div
        v-bind="$attrs"
        @mouseenter="handlefocus"
        @mouseleave="handleBlur"
        :class="[
          state.focus
            ? 'placeholderClass placeholderactive'
            : 'placeholderClass',
          ,
        ]"
      >
        <span v-if="state.selectData" class="dataColor">
          {{ state.selectData }}
        </span>
        <span class="placeholder" v-else>{{ placeholder }}</span>
        <slot name="suffix" >
          <el-icon
          style="color:var(--el-border-color)"
          ><ArrowDown /></el-icon>
        </slot>
      </div>
    </template>
    <el-input
      v-model="queryParams.key"
      @change="handleFilter"
      placeholder="请输入关键字"
    />
    <div class="totalSelectV2">总数：{{ pageInfo.total }}</div>
    <el-scrollbar :height="heightData">
      <div v-infinite-scroll="handleLoad">
        <el-radio-group
          v-if="!multiple"
          class="fdc aifstart"
          v-model="state.selectValue"
          @change="handleChangeRadio"
        >
          <el-radio
            :label="item[options.value]"
            v-for="(item, index) in state.tableData"
            :key="index"
          >
            {{ item[options.label] }}
          </el-radio>
        </el-radio-group>
      </div>
    </el-scrollbar>
  </el-popover>
</template>

<script setup lang="ts">
import { ElProgress } from "element-plus";

import { ref, reactive, defineEmits, onMounted, watch, toRaw } from "vue";

const emit = defineEmits(["update:modelValue"]);

const popoverRef = ref<any>();
const state = reactive({
  focus: false,
  popover: false,
  selectValue: "",
  tableData: [],
  tableDataCopy: [],
  total: 0, //总共有几页
  selectData: "",
});
const queryParams = reactive({
  key: "",
});
const pageInfo = reactive({
  currentPage: 1,
  total: 0,
  pageSize: 20,
});
const prop = defineProps({
  modelValue: {
    type: [String],
    defalut: "",
  },
  apiFunction: {
    type: Function,
    default: () => {},
  },
  apiDefault: {
    type: Function,
    default: () => {},
  },
  placeholder: {
    type: String,
    required: true,
    default: "请选择",
  },
  //选择数据的高度
  heightData: {
    type: String,
    required: true,
    default: "300px",
  },
  multiple: {
    type: Boolean,
    default: false,
  },
  border: {
    type: Boolean,
    default: false,
  },
  pageInfo: {
    type: Object,
    default: null,
  },
  options: {
    type: Object,
    default: () => ({ label: "name", value: "id", searchKey: "name" }),
  },
  filters: {
    type: Object,
    default: () => ({}),
  },
});
//单选 更新
const handleChangeRadio = () => {
  let data: any = state.tableData.find((res) => {
    return res[prop.options.value] === state.selectValue;
  });
  state.selectData = data[prop.options.label];
  emit("update:modelValue", data[prop.options.value]);
  popoverRef.value?.hide();
};
//获取焦点
const handlefocus = () => {
  if (prop.border) return;
  state.focus = true;
};
//失去焦点
const handleBlur = () => {
  //如果 弹框展示就禁止隐藏
  if (state.popover || prop.border) return;
  state.focus = false;
};
//设置筛选条件
const setFilter = () => {
  let searchKey = prop.options.searchKey
    ? prop.options.searchKey
    : prop.options.label;
  getList({
    [searchKey]: queryParams.key,
  });
};
//过滤当前数据
const handleFilter = () => {
  pageInfo.currentPage = 1;
  setFilter();
};
//下拉加载
const handleLoad = (e: any) => {
  if (state.total <= pageInfo.currentPage) return;
  pageInfo.currentPage += 1;
  setFilter();
};
//打开选择器
const getList = (data?: any) => {
  let parmas = {};
  if (data) {
    parmas = {
      ...data,
    };
  }
prop.apiFunction({
    ...pageInfo,
    ...prop.filters,
    ...parmas, //筛选条件
  }).then((response: any) => {
    pageInfo.total = response.total;
    let data = response.total ? response.rows : response.data;
    if (pageInfo.total) {
      state.total = Math.ceil(response.total / pageInfo.pageSize);
    }
    if (pageInfo.currentPage <= 1) {
      state.tableData = data;
    } else {
      state.tableData = state.tableData.concat(data);
    }
    state.tableDataCopy =toRaw(state.tableData)
  });
};
watch(
  () => prop.pageInfo,
  (val: any) => {
    if (val) {
      Object.assign(pageInfo, val);
    }
  },
  {
    deep: true,
    immediate: true,
  },
);
watch(
  () => prop.modelValue,
  (val: any) => {
    if (Boolean(val)) {
      if (state.tableData.length == 0) {
      prop.apiDefault(val).then((response: any) => {
          let data = response.data;
          state.selectData = data[prop.options.label];
        });
      }
    }
  },
  {
    deep: true,
    immediate: true,
  },
);
watch(
  () => prop.multiple,
  (val: any) => {
    if (val) {
      state.selectValue = val.split(",");
    } else {
      state.selectValue = val;
    }
  },
  {
    deep: true,
    immediate: true,
  },
);
watch(
  () => prop.border,
  (val: any) => {
    if (val) {
      state.focus = true;
    }
  },
  {
    deep: true,
    immediate: true,
  },
);
//显示 弹框
const handlePopoverShow = () => {
  state.popover = true;
  if (state.tableData.length == 0) {
    getList();
  }
};
//隐藏弹框
const handlePopoverHide = () => {
  state.popover = false;
  if (prop.border) return;
  state.focus = false;
};
</script>

<style scoped lang="scss">
.w250 {
  width: 250px;
}
.dataColor {
  color: var(--el-input-text-color, var(--el-text-color-regular));
}
.placeholder{
  color: var(--el-text-color-placeholder);
}
.placeholderClass {
  display: inline-block;
 color: var(--el-text-color-regular);
  width: 100%;
  height: var(--el-input-inner-height);
  padding: 0px 8px;
  box-sizing: border-box;
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: pointer;
  border: 1px solid transparent;
  border-radius: var(--el-border-radius-base);
  box-shadow: 0 0 0 1px var(--el-border-color) inset;
}
.placeholderactive {
  border-radius: 5px;
  // border: 1px solid #eee;
  box-shadow: 0 0 0 1px var(--el-border-color) inset;
}
.totalSelectV2 {
  font-size: 12px;
  padding-bottom: 4px;
  padding-left: 12px;
  padding-top: 4px;
  line-height: 20px;
    color: var(--el-text-color-secondary);
}
</style>
